#encoding: utf-8
=begin

Usage:      Libs for split-orders

=end

load 'rds_api.rb'
load 'crmeb_utils.rb'

def get_orders_ conditions
  puts "retrieving orders #{conditions}"
  orders = []
  inq = "select * from crmeb.eb_store_order "
  inq += conditions.empty? ? ';' : " #{conditions};"
  res = queryRds inq
  res.each { |order| orders += [order] }
  return orders
end

def get_orders_during stime, etime
  return get_orders_ "where add_time >= #{stime.to_i} and add_time <= #{etime.to_i}"
end

def leave_alone? order
  return order['order_code'].to_s.include? 'FC'
end

def pickup_able? order
  return order['shipping_type'] == 2
end

#根据邮件模版数量返回多个cart, 每个邮件模版一个cart
def group_cart_items order

  #首先找出所有购物车物品
  cart_infos = []
  inq = "select * from crmeb.eb_store_order_cart_info where oid = #{order['id']};"
  queryRds(inq).each {|r| cart_infos += [r['cart_info']]}

  #用temp_id作为键值重组carts, 每个包邮组装入一个cart
  carts = {} 
  cart_infos.each do |cart_info|

    item = JSON.parse cart_info
    temp_id = item['productInfo']['temp_id']

    carts.store temp_id, [] if carts[temp_id].nil?
    cart = carts[temp_id]
    cart += [item]
    carts.store temp_id, cart

  end
  return carts

end

#按照拆分后应有的订单数克隆出拆分后的订单原型,以DRV结尾, deriv
def clone_deriv_orders_from order

  #这里没有放入 source_mid, 这个字段默认是为零的，只有到拆分时，才会根据同一包邮组下具体商品的source_mid赋予
  fields=['id','order_id','uid','real_name','user_phone','user_address','cart_id','freight_price','total_num','total_price','total_postage','pay_price','pay_postage','deduction_price','coupon_id','coupon_price','paid','pay_time','pay_type','add_time','status','refund_status','refund_reason_wap_img','refund_reason_wap_explain','refund_reason_time','refund_reason_wap','refund_reason','refund_price','gain_integral','use_integral','back_integral','mark','is_del','unique','remark','mer_id','combination_id','pink_id','cost','seckill_id','bargain_id','verify_code','store_id','shipping_type','clerk_id','is_channel','is_remind','is_system_del','order_code','misc']

  sqls = ['use crmeb;']

  carts = group_cart_items order
  (carts.size-1).times do |idx|

    #insert into 表1(字段1,字段2,字段3) select 字段1,字段2,字段3 from 表1 where id=1
    #如果不用"`"，则unique字段将导致出错
    sql = "insert into crmeb.eb_store_order ("
    fields[1..fields.length-1].each { |field| sql += " `#{field}`," }
    sql[sql.length-1] = ')' #remove last comma
    sql += " select "
    (1..fields.length-1).each do |i|
        field = fields[i]
        case field
        when 'unique'
          sql += " getUUID(uuid()),"
        when 'order_id'
          sql += " '#{order['order_id']}DRV#{idx+1}',"
        #商品数、总价、运费、等，不从原始订单继承
        when 'total_num', 'total_price', 'total_postage', 'pay_price', 'pay_postage', 'deducation_price', 'gain_integral',  'use_integral', 'coupon_price'
          sql += " 0,"
        else
          sql += " `#{field}`,"
        end
    end
    sql[sql.length-1] = ' '
    sql += " from crmeb.eb_store_order where id = #{order['id']};"

    sqls += [sql]

  end
  commitTrans sqls

end

def get_template_postage order, temp_id
  misc = {}
  begin
    misc = JSON.parse order['misc'].to_s
    if misc['tempPostages'] && misc['tempPostages']["#{temp_id}"] #目前的temp_id键值是字符串，返回值有数字零，也有字符串，在StoreOrder Model一侧需要改进
      postage = misc['tempPostages']["#{temp_id}"]  
      return postage.class == Float ? postage : postage.to_f
    end
  rescue => e
  end
  return 0
end

def fork_orders_by order

  clone_deriv_orders_from order

  #get all forked orders
  forked_orders = [order]
  inq = "select * from crmeb.eb_store_order where order_id like '#{order['order_id']}DRV%'" #注意'-'不能作为后台接口查询参数
  queryRds(inq).each { |r| forked_orders += [r] }

  #建立路线数组，将所有的购物车及订单Hash化
  routes = []
  orders = {}
  item_list = {}
  appendix = {}

  #通过原始订单中的所有商品项目总表，按照不同的邮费模版，将订单与模版建立联系
  idx = 0
  carts = group_cart_items order
  carts.each do |route,items|
    routes += [route]
    orders.store route, forked_orders[idx] #每条线路对应的订单
    tmp_list = []
    items.each { |item| tmp_list += [item['id']]}
    item_list.store route, tmp_list #每条线路下的购物车项目
    appendix.store route, "#{idx}" #子单号
    idx += 1
  end 

  #用原生订单的内部id生成订单编码的主要部分
  order_code_base = sprintf("%08d",order['id'])

  #遍历每条线路，更新订单，更新item中的对应订单号
  routes.each do |route|

    this_cart = carts[route]
    this_order = orders[route]
    this_list = item_list[route]

    if this_order.nil?
      puts "ERROR>>>>"
      puts "questioned route:"
      ap route
      puts "original order:"
      ap order
      puts "routes:"
      ap routes
      puts "carts:"
      ap carts
      puts "orders:"
      ap orders
      puts "<<<<EXIT"
      exit
    end

    #找出本条包邮规则下第一个商品对应的mer_id,source_mid和temp_id,以便生成分拣单号
    cart_item_id = item_list[route][0]
    mer_id = 0
    source_mid = 0
    temp_id = 0
    #sel = "select p.temp_id, c.mer_id from crmeb.eb_store_order_cart_info as c left join crmeb.eb_store_product as p on c.product_id = p.id where cart_id = #{cart_item_id};" #此查询在某些情况下，无法获得temp_id
    sel = "select mer_id, source_mid, cart_info from crmeb.eb_store_order_cart_info where cart_id = #{cart_item_id};"
    queryRds(sel) .each do |m|
      mer_id = m['mer_id']
      source_mid = m['source_mid']
      sel_cart_info = JSON.parse m['cart_info']
      temp_id = sel_cart_info["productInfo"]["temp_id"]
      break
    end

    #准备分拣单号
    order_code = "FC#{order_code_base}-#{carts.size}#{appendix[route]}M#{mer_id}S#{temp_id}"

    #准备总价及商品数量
    cart_id = this_list.to_json
    total_num = 0
    total_price = 0
    this_cart.each do |item|
      total_num += item['cart_num']
      begin
        total_price += item['truePrice'] * item['cart_num']
      rescue => e
        total_price += item['truePrice'].to_f * item['cart_num'] #当订单为拼团单，即pink_id != 0 时, truePrice现在是个愚蠢的字符串
      end
    end

    #remark = "已拆分订单 " + this_order['remark'].to_s if carts.size > 1 # to_s to avoid NULL exception 无需更新了

    #准备运费
    total_postage = get_template_postage this_order, temp_id
    total_postage = 0 if this_order['shipping_type'] == 2 #自提订单, 然而邮件模板处仍有记录运费

    #扣减前应支付的总金额
    total_cost = total_postage + total_price

    #获得原生订单的总应付
    whole_cost = order['total_price'] + order['total_postage']
    whole_cost = order['total_price'] if order['shipping_type'] == 2 #自提订单，以防万一
    whole_integral = order['use_integral']
    whole_deduction = order['deduction_price']
    whole_coupon = order['coupon_price']

    #按比例计算抵扣积分及优惠券金额
    use_integral = this_order['use_integral']       #本订单用掉的积分,非原生订单创建后为零
    deduction_price = this_order['deduction_price'] #本订单用积分（或折扣券）抵用掉的金额, 非原生订单创建后为零
    coupon_price = this_order['coupon_price'] #本订单用优惠券抵扣掉的金额，非原生订单创建后为零
    use_integral = whole_cost == 0 ? 0 : ( whole_integral * total_cost / whole_cost ).round(2)
    deduction_price = whole_cost == 0 ? 0 : ( whole_deduction * total_cost / whole_cost ).round(2)
    coupon_price = whole_cost == 0 ? 0 : (whole_coupon * total_cost / whole_cost).round(2)

    #使用coupon的时候也应该计算在内
    #TBD

    #根据抵扣积分计算子订单的实际支付金额
    pay_price = order['pay_price'] > 0 ? total_cost - deduction_price - coupon_price : 0
    pay_postage = order['pay_postage'] > 0 ? total_postage : 0 #如果原生订单中有付过邮费
    
    #update key fields: order_id, cart_id, total_num, total_price in eb_store_order
    inq = "update crmeb.eb_store_order set 
              order_code = '#{order_code}', cart_id = '#{cart_id}', total_num = #{total_num}, total_price = #{total_price},
              total_postage = #{total_postage}, pay_postage = #{pay_postage}, pay_price = #{pay_price},
              use_integral = #{use_integral}, deduction_price = #{deduction_price}, coupon_price = #{coupon_price},
              mer_id=#{mer_id}, source_mid = #{source_mid}
            where id = #{this_order['id']};"
    queryRds inq

    #update order id in eb_store_order_cart_info
    this_cart.each do |item|
      inq = "update crmeb.eb_store_order_cart_info set oid = #{this_order['id']} where cart_id = #{item['id']};"
      queryRds inq
    end

    #这里面还有一些其他问题需要捋清楚 - 1）其实独立商店按理是不会出现其它人的商品的

  end

  

    #接下来处理多商户的订单信息记录

    #首先删除原来的多商户订单记录，可以通过原始order_id，因为单拆开以后，单上如果已经没有该商户的商品，就会显示一张空订单
    inq = "delete from crmeb.eb_store_order_merchant where oid = #{order['id']}"
    res = queryRds inq

    #其次再根据eb_store_order_cart_info，找出每个新的order_id的对应记录，汇总所对应的mer_id，每一个mer_id的，都生成一组对应的mer_order与oid的对应记录写入eb_store_order_merchat
    forked_orders.each do |this_order|

      mer_ids = {}
      inq = "select mer_id from eb_store_order_cart_info where oid = #{this_order['id']}"
      res = queryRds inq
      res.each { |r| mer_ids[r['mer_id']] = this_order['id'] }

      mer_ids.each do |mer_id, order_id|
        inq = "insert into crmeb.eb_store_order_merchant( mer_id, oid, add_time ) values ( #{mer_id}, #{order_id}, #{Time.now.to_i} );"
        queryRds inq
      end

    end


  inq = "select * from crmeb.eb_store_order where order_id like '#{order['order_id']}%'"
  res = queryRds inq
  orders = []
  res.each { |order| orders += [order] }
  return orders

end

def split_orders orders

  new_orders = []

  orders.each do |order|
    if leave_alone? order
      #带有FC标识，已被拆分处理过
      new_orders += [order]
      print ('-')
    else
      splitted_orders = fork_orders_by order
      new_orders += splitted_orders
      print ('.')
    end
  end
  puts ""

  return new_orders

end

def register_books orders
  orders.each do |order|
    update_pickup_book_for order
  end
end

def archive_orders_during stime, etime, dir_name = 'fc4-orders'

  dir = OS.windows? ? ".\\nginx\\html\\#{dir_name}\\2020\\" : "./nginx/html/#{dir_name}/2020/"
  res = @rds.query "select oid, add_time, line, phone, order_code, ship, text from crmeb.eb_pickup_book where add_time >= #{stime.to_i} and add_time <= #{etime.to_i};" #using unix_timestamp
  res.each do |r|
    fn = dir + r['order_code'].to_s + ".txt"
    File.open(fn,"w:UTF-8") { |f| f.write r['text'] }
    fn2 = dir + "ship_" + r['order_code'].to_s + ".txt"
    File.open(fn2,"w:UTF-8") { |f| f.write r['ship'] }
  end

end

def archive_orders_ conditions, dir_name = 'fc4-orders'

  return if !(conditions.include? 'where')

  dir = OS.windows? ? ".\\nginx\\html\\#{dir_name}\\2020\\" : "./nginx/html/#{dir_name}/2020/"
  res = @rds.query "select oid, add_time, line, phone, order_code, ship, text from crmeb.eb_pickup_book #{conditions};"
  res.each do |r|
    fn = dir + r['order_code'].to_s + ".txt"
    File.open(fn,"w:UTF-8") { |f| f.write r['text'] }
    fn2 = dir + "ship_" + r['order_code'].to_s + ".txt"
    File.open(fn2,"w:UTF-8") { |f| f.write r['ship'] }
  end

end
